﻿using OnWork.DataCenter.Utils;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Net.Http;

namespace OnWork.DataCenter.BLL.Standard
{
    /// <summary>
    /// Http请求对象
    /// </summary>
    public class HttpRequestDto
    {
        /// <summary>
        /// Http请求方法
        /// </summary>
        public HTTPRequestMethod Method { get; set; } = HTTPRequestMethod.GET;

        public HttpRequestDto()
        {
        }

        /// <summary>
        /// 请求地址
        /// </summary>
        public string URL { get; set; }

        /// <summary>
        /// 请求头
        /// </summary>
        public List<HTTPRequestHeaderModel> Headers { get; set; } =
                new List<HTTPRequestHeaderModel>() {
                    new HTTPRequestHeaderModel("Accept","*/*"),
                    new HTTPRequestHeaderModel("Accept-Encoding","gzip, deflate, br"),
                    new HTTPRequestHeaderModel("User-Agent","Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36"),
                    new HTTPRequestHeaderModel("Connection", "keep-alive"),
                      };

        /// <summary>
        /// 请求查询
        /// </summary>
        public List<HTTPRequestHeaderModel> Query { get; set; } = new List<HTTPRequestHeaderModel>();

        /// <summary>
        /// 请求Body类型
        /// </summary>
        public HTTPRequestBodyType BodyType { get; set; } = HTTPRequestBodyType.None;

        /// <summary>
        /// 请求Bodey
        /// </summary>
        public List<HTTPRequestHeaderModel> BodyKeyValue { get; set; } = new List<HTTPRequestHeaderModel>();
        /// <summary>
        /// Raw类型
        /// </summary>
        public string BodyRaw { get; set; }



        /// <summary>
        /// 请求对象
        /// </summary>
        public HttpResponseMessage Request(HttpClient client)
        {

            var httpRequestMessage = GetHttpMessage();

            var request = client.Send(httpRequestMessage);


            //HttpResponseMessage request = null;
            //var span = await StopwatchAsync(async () =>
            //{
            //    request = await client.SendAsync(httpRequestMessage);
            //});
            //CostTime = span.Milliseconds.ToString(); //请求花费时间ms
            return request;
        }


        private HttpRequestMessage GetHttpMessage() {

            //请求内容封装对象
            HttpRequestMessage httpRequestMessage = new HttpRequestMessage(new HttpMethod(Method.ToString()), GetURI(URL));

            //请求头内容处理
            RequestHeader(httpRequestMessage, Headers);

            // ByteArrayContent - HTTP content based on a byte array.
            //FormUrlEncodedContent - HTTP content of name / value tuples encoded using application/ x - www - form - urlencoded MIME type.
            //MultipartContent - HTTP content that gets serialized using the multipart/* content type specification.
            //MultipartFormDataContent - HTTP content encoded using the multipart/form-data MIME type.
            //StreamContent - HTTP content based on a stream.
            //StringContent - HTTP content based on a string.

            switch (BodyType)
            {
                case HTTPRequestBodyType.None:
                    //不执行操作
                    break;
                case HTTPRequestBodyType.FromData:
                    var FromDataContent = new MultipartFormDataContent();

                    var FromDataString = GetAviableModel(BodyKeyValue);
                    foreach (var item in FromDataString)
                    {
                        FromDataContent.Add(new StringContent(item.Value), item.Key);
                    }

                    httpRequestMessage.Content = FromDataContent;
                    break;
                case HTTPRequestBodyType.XWwwForm:
                    List<KeyValuePair<string, string>> keyValuePairs = new List<KeyValuePair<string, string>>();
                    var bodyKeyValues = GetAviableModel(BodyKeyValue);
                    foreach (var item in bodyKeyValues)
                    {
                        keyValuePairs.Add(new KeyValuePair<string, string>(item.Key, item.Value));
                    }
                    var FormUrlEncodedContent = new FormUrlEncodedContent(keyValuePairs);
                    httpRequestMessage.Content = FormUrlEncodedContent;
                    break;
                case HTTPRequestBodyType.Json:
                    HttpContent contentJson = new StringContent(BodyRaw);
                    contentJson.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/json");
                    httpRequestMessage.Content = contentJson;
                    break;
                case HTTPRequestBodyType.Xml:
                    HttpContent contentXML = new StringContent(BodyRaw);
                    contentXML.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/xml");
                    httpRequestMessage.Content = contentXML;
                    break;
                case HTTPRequestBodyType.Raw:
                    HttpContent contentText = new StringContent(BodyRaw);
                    contentText.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("text/plain");
                    httpRequestMessage.Content = contentText;
                    break;
                case HTTPRequestBodyType.Binary:
                    break;
                default:
                    break;
            }

            //选择text，则请求头是： text/plain
            //选择javascript，则请求头是： application/javascript
            //选择json，则请求头是： application/json(如果想以json格式传参，就用raw + json就行了)
            //选择html，则请求头是： text/html
            //选择application / xml，则请求头是： application / xml

            //httpRequestMessage.Headers.Add("Accept", "application/json");
            return httpRequestMessage;

        }

        /// <summary>
        /// 请求对象异步
        /// </summary>
        public async Task<HttpResponseMessage> RequestAsync(HttpClient client)
        {
            //client.DefaultRequestHeaders.Accept.Clear();

            //if (headers.Count()>0)
            //{
            //    foreach (var header in headers)
            //    {
            //        client.DefaultRequestHeaders.Add(header.Key,header.Value);
            //    }
            //}


            var httpRequestMessage = GetHttpMessage();

            var request = await client.SendAsync(httpRequestMessage);




            //HttpResponseMessage request = null;
            //var span = await StopwatchAsync(async () =>
            //{
            //    request = await client.SendAsync(httpRequestMessage);
            //});
            //CostTime = span.Milliseconds.ToString(); //请求花费时间ms
            return request;

            //await client.GetAsync(uRL);

            //client.DefaultRequestHeaders.Accept.Add(

        }

        /// <summary>
        /// 获取可使用的对象
        /// </summary>
        /// <param name="list"></param>
        private List<HTTPRequestHeaderModel> GetAviableModel(List<HTTPRequestHeaderModel> list)
        {
            return list.Where(x => !string.IsNullOrEmpty(x.Key) && !string.IsNullOrEmpty(x.Value)).ToList();
        }

        /// <summary>
        /// 获取URI对象
        /// </summary>
        /// <param name="url"></param>
        /// <returns></returns>
        private Uri GetURI(string url)
        {
            string[] types = new string[] { "http://", "https://" };

            url = url.Trim(); //去空格
            if (url.StartsWith(types[0]) || url.StartsWith(types[1]))
            {
                //包含则不处理
            }
            else
            {
                //不包含添加 http
                url = types[0] + url;
            }



            //如果查询不为空
            if (Query != null)
            {
                //可以使用的头内容
                var aviables = Query.Where(x => !string.IsNullOrEmpty(x.Key) && !string.IsNullOrEmpty(x.Value)).ToList();
                if (aviables != null && aviables.Count > 0)
                {

                    var keylist = aviables.Select(x => x.Key + "=" + x.Value).ToList();
                    var param = string.Join("&", keylist);

                    //截取?前的数据 Baseapi
                    var index = url.IndexOf("?", StringComparison.OrdinalIgnoreCase);
                    if (index != -1)
                    {
                        //获取基础
                        url = url.Substring(0, index);
                    }
                    url = url + "?" + param;
                }
            }

            URL = url.Formula();//处理公式 ${}
            var httpuri = new Uri(URL);
            return httpuri;
        }

        /// <summary>
        /// 请求头处理
        /// </summary>
        /// <param name="httpRequestMessage"></param>
        private void RequestHeader(HttpRequestMessage httpRequestMessage, IList<HTTPRequestHeaderModel> headers)
        {
            if (headers != null)
            {
                //可以使用的头内容
                var aviableHeaders = headers.Where(x =>!string.IsNullOrEmpty(x.Key) && !string.IsNullOrEmpty(x.Value)).ToList();
                foreach (var header in aviableHeaders)
                {
                    httpRequestMessage.Headers.Add(header.Key, header.Value);
                }
            }
        }

    }
}